package io.mvvm.ws;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @program: Netty
 * @description:
 * @author: 潘
 * @create: 2021-04-21 19:16
 **/
@Component
public class NettyServer {

    @Resource
    private WebSocketChannelInitializer webSocketChannelInitializer;

    public void start() throws Exception {
        // 连接处理group
        EventLoopGroup boss = new NioEventLoopGroup();
        // 事件处理group
        EventLoopGroup worker = new NioEventLoopGroup();
        //1.创建ServerBootStrap实例
        ServerBootstrap bootstrap = new ServerBootstrap();
        // 绑定处理group
        //2.设置并绑定Reactor线程池：EventLoopGroup，EventLoop就是处理所有注册到本线程的Selector上面的Channel
        bootstrap.group(boss, worker)
                //3.设置并绑定服务端的channel
                .channel(NioServerSocketChannel.class)
                // 保持连接数
                .option(ChannelOption.SO_BACKLOG, 1024)
                // 有数据立即发送
                .childOption(ChannelOption.TCP_NODELAY, true)
                // 保持连接
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                // 处理新连接
                //设置了客户端连接socket属性。
                .childHandler(webSocketChannelInitializer);

        // 绑定端口，同步等待成功
        try {
            //真正让netty跑起来的重点
            ChannelFuture future = bootstrap.bind(5555).sync();
            // 等待服务监听端口关闭,就是由于这里会将线程阻塞，导致无法发送信息，所以我这里开了线程
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 优雅地退出，释放线程池资源
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
